import unittest
from chordsparser import * #@UnusedWildImport
from tabulature import *

class TestConverter(unittest.TestCase):

    def test_invalid_input (self):
        with self.assertRaises (Exception):
            ChordsParser("M")
      
    def test_simple(self):
        parser = ChordsParser("C")
        self.assertEquals (["C", "E", "G"], parser.getNotes ())
    
    def test_DiezMatches(self):
        filter = DiezFilter()
        self.assertTrue(filter.match ("C#"))
        self.assertTrue(filter.match ("Cb"))
        self.assertTrue(filter.match ("Dm#"))
        self.assertTrue(filter.match ("Emb7"))
        self.assertEquals(["C#", "F", "G#"], filter.apply ("C#", ["C", "E", "G"]))
        self.assertEquals(["C#", "F", "G#"], filter.apply ("Db", ["D", "F#", "A"]))

    def test_MinorMatches(self):
        filter = MinorFilter()
        self.assertTrue(filter.match ("Cm"))
        self.assertTrue(not filter.match ("D"))
        self.assertTrue(filter.match ("Em7"))
        self.assertTrue(filter.match ("Em#7"))
        self.assertTrue(not filter.match ("E#7"))
        self.assertTrue(not filter.match ("Cmaj"))
        
        
        self.assertEquals(["C", "D#", "G"], filter.apply ("Cm", ["C", "E", "G"]))
        self.assertEquals(["C#", "E", "G#"], ChordsParser("Dmb").getNotes())#, ["D", "F", "A"]))
        
    def test_SeptFilter(self):
        filter = SeptFilter ()
        self.assertTrue(filter.match("Cm7"))
        self.assertTrue(filter.match("C7"))
        self.assertTrue(filter.match("CmM7"))
        self.assertTrue(filter.match("Cmaj7"))
        self.assertTrue(filter.match("CM7"))

        self.assertTrue(not filter.match("Bm"))
        
        self.check ("Cm", ["C", "D#", "G"])
        self.check ("Dm7", ["D", "F", "A", "C"])
        self.check ("E7", ["E", "G#", "B", "D"])# 2/1.5/1.5
        self.check ("Am7", ["A", "C", "E", "G"]) #1.5/2/1.5
        self.check ("DM7", ["D", "F#", "A", "C#"]) #2/1.5/2
        self.check ("Gmaj7", ["G", "B", "D", "F#"])
        self.check ("BmM7", ["B", "D", "F#", "A#"])#1.5/2/2

    def test_CheckDiezSept(self):
        self.check ("G#maj7", ["G#", "C", "D#", "G"])
        self.check ("BbmM7", ["Bb", "C#", "F", "A"])#1.5/2/2
        self.check ("Abm7", ["Ab", "B", "D#", "F#"]) #1.5/2/1.5
        self.check ("C#m", ["C#", "E", "G#"])
        self.check ("Dmb7", ["Db", "Fb", "Ab", "Cb"])
        self.check ("Eb7", ["Eb", "G", "Bb", "Db"])# 2/1.5/1.5
        self.check ("DbM7", ["Db", "F", "Ab", "C"]) #2/1.5/2
        self.check ("DbM7", ["Db", "F", "Ab", "C"]) #2/1.5/2
        
    def check(self, chordString, expected):
        print "Checking notes for " + chordString
        self.assertEquals(self.bemolToDiez (expected), ChordsParser(chordString).getNotes())
    
    #bad name - converts all the notes
    #to contain only #
    def bemolToDiez (self, notes):
        newChord=list()
        for note in notes:
            if re.search("b", note) != None:
                note = ChordsParser.downHalfTone(note[0])
            newChord.append (note)
        return newChord
        
    def test_toStep(self):
        parser = ChordsParser("C")
        self.assertEquals ('C', parser.toStep (1))
        self.assertEquals ('E', parser.toStep (3))
        self.assertEquals ('G', parser.toStep (5))

        self.check ("Cm", ["C", "D#", "G"])

        self.check("G", ["G", "B", "D"])
        self.check("D#",["D#", "G", "A#"])
        self.check("Gb", ["F#", "A#", "C#"])
        self.check("Cb",["B", "D#", "F#"])
        self.check("B#",["C", "E", "G"])

        
    def test_Finale(self):
        self.check ("Cm", ["C", "D#", "G"]) #3rd down 1/2
        
    @unittest.skip("prototyping")
    def test_TabLines(self):
        parser = ChordsParser("E")
        notes = parser.getNotes()
        line = TabLine (0)#0 means upper E
        line.notch (notes)
        # shows steps on the line
        
        
    @unittest.skip("prototyping")
    def test_Tabulature(self):
        tab = Tabulature("Em")
        self.assertEquals("022000", tab.getModel())
        view = TabulatureView (tab)
        self.assertEquals(view.getLine(0), "------")
        self.assertEquals(view.getLine(1), "-*----")
        self.assertEquals(view.getLine(2), "-*----")
        self.assertEquals(view.getLine(3), "------")
        self.assertEquals(view.getLine(4), "------")
        self.assertEquals(view.getLine(5), "------")
        
if __name__ == '__main__':
    unittest.main()
